package com.sunchangming.uniqname;

import java.sql.DriverManager;
import java.sql.SQLException;

import org.apache.log4j.Logger;

import com.google.protobuf.RpcController;
import com.google.protobuf.ServiceException;
import com.sunchangming.uniqname.UniqMsg.AllocateRequest;
import com.sunchangming.uniqname.UniqMsg.BoolResponse;
import com.sunchangming.uniqname.UniqMsg.ConfirmRequest;
import com.sunchangming.uniqname.UniqMsg.Empty;
import com.sunchangming.uniqname.UniqMsg.ExistRequest;
import com.sunchangming.uniqname.UniqMsg.RegisterMySelfRequest;
import com.sunchangming.uniqname.UniqMsg.ReleaseRequest;

public class ServiceImpl implements com.sunchangming.uniqname.UniqMsg.UniqNameService.BlockingInterface {
	private final static Logger logger = Logger.getLogger(ServiceImpl.class);

	private java.sql.Connection getSqlConnection() {
		ServiceConfig config = ServiceConfig.getInstance();
		java.sql.Connection conn;
		try {
			java.util.Properties info = new java.util.Properties();
			info.put("user", config.getJdbcusername());
			info.put("password", config.getJdbcpassword());
			info.put("characterEncoding", config.getJdbcencoding());
			conn = DriverManager.getConnection(config.getJdbcUrl(), info);
			// Do something with the Connection

		} catch (SQLException ex) {
			logger.error("连接数据库失败", ex);
			return null;
		}
		return conn;
	}

	void testJdbcConnection() throws SQLException {
		java.sql.Connection conn = this.getSqlConnection();
		conn.close();
	}

	private BoolResponse getBool(boolean v) {
		return BoolResponse.newBuilder().setValue(v).build();
	}

	@Override
	public BoolResponse allocate(RpcController c, AllocateRequest request) throws ServiceException {
		MyRpcController controller = (MyRpcController) c;
		int localid = controller.Getsession().getLocalid();
		if (localid < 0)
			return getBool(false);
		java.sql.Connection conn = getSqlConnection();
		if (conn == null)
			return getBool(false);
		boolean ret = false;
		try (java.sql.PreparedStatement st = conn
				.prepareStatement("DELETE from names where name=? and group=?  and TIMESTAMPDIFF(second,time,now())>120")) {
		} catch (SQLException ex) {
			logger.error("err", ex);
			return getBool(false);
		}
		try (java.sql.PreparedStatement st = conn
				.prepareStatement("INSERT INTO names (`group`,`name`,`localId`,`peerIp`) VALUES (?,?,?,?)")) {
			st.setString(1, request.getGroup());
			st.setString(2, request.getName());
			st.setInt(3, localid);
			st.setString(4, controller.Getsession().getRemoteAddr());
			st.executeUpdate();
			ret = true;
		} catch (java.sql.SQLIntegrityConstraintViolationException ex) {

		} catch (SQLException ex) {
			logger.error("err", ex);
		} finally {
			try {
				conn.close();
			} catch (Exception ex) {
			}
		}
		return getBool(ret);
	}

	@Override
	public BoolResponse confirm(RpcController c, ConfirmRequest request) throws ServiceException {
		MyRpcController controller = (MyRpcController) c;
		int localid = controller.Getsession().getLocalid();
		if (localid < 0)
			return getBool(false);
		java.sql.Connection conn = getSqlConnection();
		if (conn == null)
			return getBool(false);
		boolean ret = false;
		try (java.sql.PreparedStatement st = conn
				.prepareStatement("update names where TIMESTAMPDIFF(second,time,now())<120 and group=? and name=?")) {
			st.setString(1, request.getGroup());
			st.setString(2, request.getName());
			st.executeUpdate();
			ret = st.getUpdateCount() == 1;
		} catch (java.sql.SQLIntegrityConstraintViolationException ex) {

		} catch (SQLException ex) {
			logger.error("err", ex);
		} finally {
			try {
				conn.close();
			} catch (Exception ex) {
			}
		}
		return getBool(ret);
	}

	@Override
	public BoolResponse release(RpcController c, ReleaseRequest request) throws ServiceException {
		MyRpcController controller = (MyRpcController) c;
		int localid = controller.Getsession().getLocalid();
		if (localid < 0)
			return getBool(false);
		return null;
	}

	@Override
	public BoolResponse exist(RpcController c, ExistRequest request) throws ServiceException {
		MyRpcController controller = (MyRpcController) c;
		int localid = controller.Getsession().getLocalid();
		if (localid < 0)
			return getBool(false);
		return null;
	}

	@Override
	public BoolResponse registerMySelf(RpcController c, RegisterMySelfRequest request) throws ServiceException {
		MyRpcController controller = (MyRpcController) c;
		// TODO:检查localid是否重复
		if (!controller.Getsession().setLocalid(request.getLocalid()))
			return getBool(false);
		return getBool(true);
	}

	@Override
	public BoolResponse clearAll(RpcController controller, Empty request) throws ServiceException {
		java.sql.Connection conn = getSqlConnection();
		if (conn == null)
			return getBool(false);
		boolean ret = false;
		// 不能在catch中return，所以增加一个变量
		try (java.sql.Statement st = conn.createStatement()) {
			st.execute("delete from names");
			ret = true;
		} catch (SQLException ex) {
			logger.error("err", ex);
		} finally {
			try {
				conn.close();
			} catch (Exception ex) {
			}
		}
		return getBool(ret);
	}

}
